#include "includes.h"
#include "vdata_hash.h"

typedef struct
{
/*********** 串口通讯参数 ***************/
    uint32_t ubaud;
    uint8_t  udata;
    uint8_t  ustop;
    uint8_t  upari;

/*********** modbus参数 ***************/
//    struct modbus{
//        uint32_t mnum:12;
//        uint32_t mtype:4;
//        uint32_t maddr:8;
//        uint32_t mdev:8;
//    }modbus;
    uint32_t mconf[100];
    uint16_t mtout;
    uint16_t mftim;
    uint16_t mroud;
    uint16_t m1xnb;
    uint16_t m2xnb;
    uint16_t m3xnb;
    uint16_t m4xnb;

/*********** 服务器参数 ***************/
    char     sip1[50];
    uint16_t spot1;
    uint8_t  scmod;
    uint16_t shbt;
    uint8_t  stagm;
    char     stagx[10];
    uint8_t  stagy;
    uint8_t  sloop;
    uint8_t  sfrq;
    uint8_t  s2on;
    char     sip2[50];
    uint16_t spot2;

/*********** GPRS参数 ***************/
    uint8_t  reg;
    uint8_t  csq;
    char     gapn[20];
    char     gapnu[20];
    char     gapnp[20];
    char     imei[20];
    char     iccid[30];
    char     cell_info[20];
    char     carrie[30];
}vdata_param_t;

char* vdata_str2_upper(char *str)
{
    char *p = str;
    while(*p != '\0'){
        if((*p > 'a')&&(*p < 'z')){
            *p -=  ('a' - 'A');
        }
        p ++;
    }
    return str;
}

int htoi(char s[])
{
    int i;
    int n = 0;
    if (s[0] == '0' && (s[1]=='x' || s[1]=='X'))  {
        i = 2;
    }else{
        i = 0;
    }
    for(; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'f') || (s[i] >='A' && s[i] <= 'F');++i){
        if (tolower(s[i]) > '9'){
            n = 16 * n + (10 + tolower(s[i]) - 'a');
        } else{
            n = 16 * n + (tolower(s[i]) - '0');
        }
    }
    return n;
}

uint16_t vdata_get_dtu_param(uint8_t *param , uint16_t param_length ,uint8_t *put_param , vdata_param_t *nv_param)
{
    char *p = (char *)param, *q = NULL;
    uint16_t i = 0, j = 0, str_length = 0;
    int hash_value = -1;

    q = (char *)put_param;
    for(i = 0; i < param_length; i++){
        str_length = strlen(p);
        if(str_length){
            vdata_str2_upper(p);
            hash_value = PJWHash(p, str_length);
            switch(hash_value){
                case PJW_STRING_UBAUD :
                    q += sprintf(q , "UBAUD:%d" , nv_param->ubaud);
                    *q++ = '\0';
                    break;

                case PJW_STRING_UDATA :
                    q += sprintf(q , "UDATA:%d" , nv_param->udata);
                    *q++ = '\0';
                    break;

                case PJW_STRING_USTOP :
                    q += sprintf(q , "USTOP:%d" , nv_param->ustop);
                    *q++ = '\0';
                    break;

                case PJW_STRING_UPARI :
                    q += sprintf(q , "UPARI:%d" , nv_param->upari);
                    *q++ = '\0';
                    break;

                case PJW_STRING_MCONF  ://该参数较多，单独查询与设置
                    q += sprintf(q , "MCONF:");
                    for(j = 0; j< 100; j++){
                        if(nv_param->mconf[j]){
                            q += sprintf(q , "%04X," , nv_param->mconf[j]);
                        }
                    }
                    q[-1] = '\0';
                    *q++ = '\0';
                    break;

                case PJW_STRING_MTOUT :
                    q += sprintf(q , "MTOUT:%d" , nv_param->mtout);
                    *q++ = '\0';
                    break;

                case PJW_STRING_MFTIM :
                    q += sprintf(q , "MFTIM:%d" , nv_param->mftim);
                    *q++ = '\0';
                    break;

                case PJW_STRING_MROUD :
                    q += sprintf(q , "MROUD:%d" , nv_param->mroud);
                    *q++ = '\0';
                    break;

                case PJW_STRING_M1XNB :
                    q += sprintf(q , "M1XNB:%d" , nv_param->m1xnb);
                    *q++ = '\0';
                    break;

                case PJW_STRING_M2XNB :
                    q += sprintf(q , "M2XNB:%d" , nv_param->m2xnb);
                    *q++ = '\0';
                    break;

                case PJW_STRING_M3XNB :
                    q += sprintf(q , "M3XNB:%d" , nv_param->m3xnb);
                    *q++ = '\0';
                    break;

                case PJW_STRING_M4XNB :
                    q += sprintf(q , "M4XNB:%d" , nv_param->m4xnb);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SIP1  :
                    q += sprintf(q , "SIP1:%s" , nv_param->sip1);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SPOT1 :
                    q += sprintf(q , "SPOT1:%d" , nv_param->spot1);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SCMOD :
                    q += sprintf(q , "SCMOD:%d" , nv_param->scmod);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SHBT  :
                    q += sprintf(q , "SHBT:%d" , nv_param->shbt);
                    *q++ = '\0';
                    break;

                case PJW_STRING_STAGM :
                    q += sprintf(q , "STAGM:%d" , nv_param->stagm);
                    *q++ = '\0';
                    break;

                case PJW_STRING_STAGX :
                    q += sprintf(q , "STAGX:%s" , nv_param->stagx);
                    *q++ = '\0';
                    break;

                case PJW_STRING_STAGY :
                    q += sprintf(q , "STAGY:%d" , nv_param->stagy);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SLOOP :
                    q += sprintf(q , "SLOOP:%d" , nv_param->sloop);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SFRQ  :
                    q += sprintf(q , "SFRQ:%d" , nv_param->sfrq);
                    *q++ = '\0';
                    break;

                case PJW_STRING_S2ON  :
                    q += sprintf(q , "S2ON:%d" , nv_param->s2on);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SIP2  :
                    q += sprintf(q , "SIP2:%s" , nv_param->sip2);
                    *q++ = '\0';
                    break;

                case PJW_STRING_SPOT2 :
                    q += sprintf(q , "SPOT2:%d" , nv_param->spot2);
                    *q++ = '\0';
                    break;

                case PJW_STRING_GAPN  :
                    q += sprintf(q , "GAPN:%s" , nv_param->gapn);
                    *q++ = '\0';
                    break;

                case PJW_STRING_GAPNU :
                    q += sprintf(q , "GAPNU:%s" , nv_param->gapnu);
                    *q++ = '\0';
                    break;

                case PJW_STRING_GAPNP :
                    q += sprintf(q , "GAPNP:%s" , nv_param->gapnp);
                    *q++ = '\0';
                    break;

                default:break;
            }
            p += str_length + 1;
            i += str_length + 1;
        }
    }
    return ((uint32_t)q - (uint32_t)put_param);
}

uint16_t vdata_set_dtu_param(uint8_t *param , uint16_t param_length ,vdata_param_t *nv_param)
{
    char *p = (char *)param, *q = NULL;
    uint16_t i = 0, index = 0, str_length = 0;
    int hash_value = -1;

    for(i = 0; i < param_length; i++){
        str_length = strlen(p);
        if(str_length){
            q = strstr(p, ":");
            vdata_str2_upper(p);
            hash_value = PJWHash(p, q - p);
            switch(hash_value){
                case PJW_STRING_UBAUD :
                    nv_param->ubaud = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_UDATA :
                    nv_param->udata = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_USTOP :
                    nv_param->ustop = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_UPARI :
                    nv_param->upari = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_MCONF  ://该参数较多，单独查询与设置
                    memset(nv_param->mconf, 0, sizeof(nv_param->mconf));
                    printf("%s\r\n", q + 1);
                    do{
                        nv_param->mconf[index++] = htoi(q + 1);
                        q = strstr(q + 1, ",");
                    }while(q);
                    break;

                case PJW_STRING_MTOUT :
                    nv_param->mtout = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_MFTIM :
                    nv_param->mftim = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_MROUD :
                    nv_param->mroud = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_M1XNB :
                    nv_param->m1xnb = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_M2XNB :
                    nv_param->m2xnb = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_M3XNB :
                    nv_param->m3xnb = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_M4XNB :
                    nv_param->m4xnb = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SIP1  :
                    strcpy((char *)nv_param->sip1 , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SPOT1 :
                    nv_param->spot1 = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SCMOD :
                    nv_param->scmod = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SHBT  :
                    nv_param->shbt = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_STAGM :
                    nv_param->stagm = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_STAGX :
                    strcpy((char *)nv_param->stagx , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_STAGY:
                    nv_param->stagy = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SLOOP :
                    nv_param->sloop = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SFRQ  :
                    nv_param->sfrq = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_S2ON  :
                    nv_param->s2on = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SIP2  :
                    strcpy((char *)nv_param->sip2 , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_SPOT2 :
                    nv_param->spot2 = atoi(q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_GAPN  :
                    strcpy((char *)nv_param->gapn , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_GAPNU :
                    strcpy((char *)nv_param->gapnu , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                case PJW_STRING_GAPNP :
                    strcpy((char *)nv_param->gapnp , q + 1);
                    printf("%s\r\n", q + 1);
                    break;

                default:break;
            }
            p += str_length + 1;
            i += str_length + 1;
        }
    }
    return 0;
}

vdata_param_t nv_param;
uint8_t data[] = {"mconf:1011,1012,1013,105f,15fc\0"};
uint8_t data1[] = {"mconf\0"};
char out_conf[1024];
int main(void)
{
    vdata_set_dtu_param(data, sizeof(data), &nv_param);
    vdata_get_dtu_param(data1, sizeof(data1), out_conf, &nv_param);
    printf("\r\n%s\r\n", out_conf);
    return 0;
}
